home *** CD-ROM | disk | FTP | other *** search
- /************************************************************************/
- /* BSTONE operations module */
- /************************************************************************/
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <alloc.h>
- #include "t_cio.h"
- #include "t_lex.h"
- #include "vector.h"
- #include "bstone_m.h"
-
- CMD_LINE program[MAX_LINES];
- int gosub_stack[MAX_LINES/10];
- int gosub_ptr=0;
- int cont_line=-1;
- int program_ctr=-1;
- int transl_flag=0;
- int cmdl,flev;
- FILE *fp[10];
- char cline[LSIZE];
- int clinep;
- char *clines;
- char err_msg[BSIZE];
- char tmp_line[LSIZE];
-
- static int bdebug;
-
- /* Error messages etc. */
- /* err: Error number. */
- /* 0: regular message */
- /* 1: print error message */
- /* 2: dito, read line until end */
- /* 3: Syntax error */
- /* 4: dito, read line until end */
- /* 5: Lex error, read line until end */
- /* 6: Expression error */
- /* 7: Error during execution */
- /* 8: Break requested */
- void basic_error(int err)
- {
- LEX *lex;
-
- if((program_ctr>0) && (program_ctr<MAX_LINES))
- fprintf(stderr,"@L%d: ",program[program_ctr-1].n);
- else
- fprintf(stderr,"@C%d: ",cmdl);
- fprintf(stderr,"ERROR: ",err);
- if(errlog!=stderr)
- {
- fprintf(errlog,"\nERROR(%d) at line %d or command %d ",
- err,(program_ctr>0) ? program[program_ctr-1].n : -1,cmdl);
- fprintf(errlog,"\nLex-Msg: %s",t_pos());
- }
- switch(err)
- {
- case 0: fprintf(stderr,"OK."); break;
- case 1: fprintf(stderr,"%s",err_msg);
- if(errlog!=stderr) fprintf(errlog,"%s",err_msg); break;
- case 2: fprintf(stderr,"%s",err_msg);
- if(errlog!=stderr) fprintf(errlog,"%s",err_msg); goto la_err1;
- case 3: fprintf(stderr,"Syntax analysis failed."); break;
- case 4: fprintf(stderr,"Syntax analysis failed."); goto la_err1;
- case 5: fprintf(stderr,"Lexical analysis failed."); goto la_err1;
- case 6: fprintf(stderr,"Wrong expression."); break;
- case 7: fprintf(stderr,"Error occured during execution."); break;
- case 8: fprintf(stderr,"Break requested."); break;
- default: fprintf(stderr,"Unknown.");
- la_err1: /* read line until end */
- lex=t_lex(NULL,LEX_PUSH);
- lex=t_lex(NULL,NO_FORCE);
- while((lex->typ!=EOLN) && (lex->typ!=EOLX))
- {
- lex=t_lex(NULL,NO_FORCE);
- }
- break;
- }
- fprintf(stderr,"\n");
- return;
- }
-
- /* clear program pointer etc. */
- void clear_program(void)
- {
- ybdebug=bdebug;
- gosub_ptr=0;
- program_ctr=-1;
- cont_line=-1;
- errlogz=stderr;
- return;
- }
-
- /* delete vars */
- void del_vars(T_NODE * tnode)
- {
- DIM_H *dm;
-
- if(tnode->c>0) switch(tnode->c)
- {
- case B_FLD: dm=(DIM_H *)(tnode->p);
- #ifdef __TURBOC__
- farfree(dm->f);
- #else
- free(dm->f);
- #endif
- break;
- default: break;
- }
- tnode->p=(void *)NULL;
- return;
- }
-
- /* Deletes program and variables */
- void new(void)
- {
- int i;
- POV_OBJ *pv;
-
- t_symdel(del_vars);
- gosub_ptr=0;
- program_ctr=-1;
- cont_line=-1;
-
- for(i=0;i<MAX_LINES;i++)
- {
- program[i].n=-1;
- if(program[i].s!=(char *)NULL) free(program[i].s);
- program[i].s=(char *)NULL;
- }
-
- for(i=0;i<PSIZE;i++)
- if((pv=obj_all[i])!=(POV_OBJ *)NULL)
- { if(pv->s!=(char *)NULL) free(pv->s);
- free(pv);
- obj_all[i]=(POV_OBJ *)NULL;
- }
- return;
- }
-
- /* finds counter for line equal or greater n */
- int search_line(int n)
- {
- int i,k,l;
-
- i=MAX_LINES-1; k=MAX_LINES/2;
- do { l=i-k; if((unsigned)(program[l].n)>=n) i=l; k>>=1; }
- while(k);
- return(i);
- }
-
- /* inserts line s at n, allocates memory for s */
- /* if s==NULL, delete line n */
- int insert_line(int n, char *s)
- {
- int l,k;
- static char msg[]={"Inserting/Deleting Line"};
- if(*s==(char)0) s=(char *)NULL;
-
- l=search_line(n);
- if(bdebug) fprintf(errlog,"%s %d (next %d)\n",msg,n,program[l].n);
- if(program[l].n==n) /* line existing yet */
- {
- if(program[l].s!=(char *)NULL) free(program[l].s);
- if(s==(char *)NULL) /* delete line */
- {
- for(k=l;k<MAX_LINES-1;k++)
- {
- program[k].n=program[k+1].n;
- program[k].s=program[k+1].s;
- }
- program[MAX_LINES-1].n=-1;
- program[MAX_LINES-1].s=(char *)NULL;
- }
- }
- else if(s!=(char *)NULL)
- {
- if(program[MAX_LINES-1].s!=(char *)NULL) t_error(msg,4);
- for(k=MAX_LINES-1;k>l;k--)
- {
- program[k].n=program[k-1].n;
- program[k].s=program[k-1].s;
- }
- }
- if(s!=(char *)NULL)
- {
- k=strlen(s);
- if((program[l].s=(char *)malloc((k+1)*sizeof(char)))==(char *)NULL)
- t_error(msg,1);
- strcpy(program[l].s,s);
- program[l].n=n;
- }
- return;
- }
-
- /* translates cmd-line into internal representation */
- /* returns NULL, if error */
- char *translate_line(void)
- {
- static char msg[]={"Translating Line"};
- int err;
-
- if(bdebug) fprintf(errlog,"%s: ",msg);
- clinep=0; transl_flag=1;
-
- /* call parser here */
- /* on error call basic_error(4) */
- err=0;
- if(yyparse())
- {
- basic_error(4);
- err=1;
- }
- cline[clinep]=(char)0;
- transl_flag=0;
- if(clinep>=LSIZE-1) t_error(msg,4);
- if(bdebug) fprintf(errlog,"%s\n",retransl_line(cline));
- if(err) return((char *)NULL);
- return(cline);
- }
-
-
- /* re-translates cmd-line from internal representation */
- char *retransl_line(char *dline)
- {
- static char msg[]={"Retranslating Line"};
- int p1,p2,c,n,i,k;
- int jmp_flag;
- char *p,*s,cc;
- T_NODE *tnode;
-
- if(dline==(char *)NULL) { tmp_line[0]=(char)0; return(tmp_line); }
- jmp_flag=0;
- for(p1=0,p2=0;*(dline+p2);p2++,p1=strlen(tmp_line))
- {
- c=(*((unsigned char *)dline+p2)); p=tmp_line+p1;
- if(c>=128) /* Token? */
- {
- c=VALTOKEN(c);
- switch(c)
- {
- case B_NUM: case B_VAL: case B_OBJ:
- case B_VEC: case B_STR:
- if(!p2) { sprintf(p," LET "); p+=5; }
- s=dline+p2+1;
- n=GET4HEX(s); p2+=4;
- if((tnode=t_symfind(n))==(T_NODE *)NULL)
- {
- if(bdebug) { t_symwalk(-1,symdebug); }
- fprintf(errlog,"Did not find symbol #%4s/%d\n",s,n);
- t_error(msg,3);
- }
- switch(c)
- {
- case B_STR:
- s=(tnode->s);
- for(i=0,n=0;i<strlen(s);i++)
- { cc=*(s+i);
- switch(cc)
- { case '\n': *(p+(n++))='\\';
- *(p+(n++))='n';
- break;
- default: *(p+(n++))=cc;
- break;
- }
- }
- *(p+n)='"'; *(p+n+1)=(char)0;
- break;
- case B_NUM:
- k=search_line((int)*(double *)(tnode->p));
- if((transl_flag!=2) || !jmp_flag)
- sprintf(p,"%s",(tnode->s)+1);
- else
- sprintf(p,"%d",10*(k+1));
- jmp_flag=0;
- break;
- default: sprintf(p,"%s",tnode->s);
- break;
- }
- break;
-
- case B_FKT:
- p2+=1;
- c=(*((unsigned char *)dline+p2));
- c=VALTOKEN(c);
-
- case RND: case ABS: case V0:
- case VX: case VY: case VZ:
- case PLANE:
- sprintf(p,"%s",t_tokenstr(c));
- break;
-
- case GOTO: case GOSUB:
- sprintf(p," %s ",t_tokenstr(c));
- jmp_flag=1;
- break;
-
- default: sprintf(p," %s ",t_tokenstr(c));
- break;
- }
- }
- else
- {
- *p=c; *(p+1)=(char)(0);
- }
- }
- if((p1>=LSIZE-1) || (p2>=LSIZE-1)) t_error(msg,4);
- tmp_line[p1]=(char)0;
- return(tmp_line);
- }
-
- /* executes command */
- void exec_line(char *dline)
- {
- if(dline==(char *)NULL) return;
- clines=dline; transl_flag=0;
-
- do
- {
- clinep=0;
- if(program_ctr>=0)
- {
- clines=program[program_ctr].s;
- program_ctr++; /* Increasing program counter */
- }
- /* Parse & execute */
- if(yyparse()) { basic_error(7); program_ctr=-1; }
-
- if(program_ctr>=0)
- if((program[program_ctr].n<0) || (program_ctr>=MAX_LINES))
- { program_ctr=-1; }
- if(load_flag)
- {
- load_flag=0;
- t_setfep(fp[flev],3L);
- program_ctr=-1;
- }
-
- }
- while(program_ctr>=0);
-
- return;
- }
-
- /* increases number of parents */
- void add_objz(POV_OBJ *pv)
- {
- int n; char *s;
- static char msg[]="Adding new object parent.";
-
- if(pv==(POV_OBJ *)NULL) t_error(msg,3);
- if(pv->tex!=(POV_OBJ *)NULL) { add_objz(pv->tex); pv->tex->cnt+=1; }
- if(pv->bound!=(POV_OBJ *)NULL) { add_objz(pv->bound); pv->bound->cnt+=1; }
- if(pv->c==0) return;
- if(pv->s==(char *)NULL) t_error(msg,4);
-
- for(s=pv->s;*s;s+=5)
- { n=GET4HEX(s+1);
- if((n<0) || (n>=PSIZE) || (obj_all[n]==(POV_OBJ *)NULL))
- t_error(msg,3);
- obj_all[n]->cnt+=1;
- add_objz(obj_all[n]);
- }
- return;
- }
-
- POV_OBJ *obj_asn(POV_OBJ *pv1, POV_OBJ *pv2)
- {
- int i;
- POV_OBJ pvx;
- static char msg[]="Assignment of objects.";
-
- if(pv2==(POV_OBJ *)NULL) t_error(msg,3);
-
- pvx.c=pv2->c;
- for(i=0;i<3;i++)
- {
- pvx.b[i]=pv2->b[i]; pvx.u[i]=pv2->u[i];
- pvx.v[i]=pv2->v[i]; pvx.w[i]=pv2->w[i];
- }
- pvx.s=cp_str(pv2->s);
- pvx.tex=pv2->tex;
- pvx.bound=pv2->bound;
-
- if(pv2->cnt>=0) add_objz(pv2); /* pvx is new parent of pv2 */
- /* objects with count < 0 are temporary !! */
-
- if(pv1==(POV_OBJ *)NULL) pv1=new_obj();
- else free_obj(pv1);
-
- pv1->cnt=1;
- pv1->c=pvx.c;
- for(i=0;i<3;i++)
- {
- pv1->b[i]=pvx.b[i]; pv1->u[i]=pvx.u[i];
- pv1->v[i]=pvx.v[i]; pv1->w[i]=pvx.w[i];
- }
- pv1->s=pvx.s;
- pv1->tex=pvx.tex;
- pv1->bound=pvx.bound;
-
- return(pv1);
- }
-
-
- POV_OBJ *add_obj(POV_OBJ *pv1,POV_OBJ *pv2)
- {
- POV_OBJ *pv; int n,i,n1,n2;
- char *s;
- static char msg[]="Adding object.";
-
- if(pv1==(POV_OBJ *)NULL)
- { pv1=new_obj(); pv1->c=1; }
- else
- if(pv1->c==0)
- { pv=add_obj((POV_OBJ *)NULL,pv1);
- pv=add_obj(pv,pv2);
- return(pv);
- }
-
- if(pv2==(POV_OBJ *)NULL) return(pv1);
-
- n=new_objz();
- pv=obj_all[n];
- pv->c=pv2->c;
- for(i=0;i<3;i++)
- {
- pv->b[i]=pv2->b[i]; pv->u[i]=pv2->u[i];
- pv->v[i]=pv2->v[i]; pv->w[i]=pv2->w[i];
- }
- pv->s=cp_str(pv2->s);
- pv->tex=pv2->tex;
- pv->bound=pv2->bound;
-
- add_objz(pv2); /* pv is new parent of pv2 */
- sprintf(tmp_line,":%04.4X",n);
-
- /* cat string */
- if(pv1->s==(char *)NULL) pv1->s=cp_str(tmp_line);
- else
- {
- n1=strlen(pv1->s); n2=strlen(tmp_line);
- n=(n1+n2)/SSIZE;
- if(n==n1/SSIZE) strcat(pv1->s,tmp_line);
- else
- {
- n=(n+1)*SSIZE;
- if((s=(char *)malloc(n))==(char *)NULL) t_error(msg,1);
- strcpy(s,pv1->s);
- strcat(s,tmp_line);
- free(pv1->s);
- pv1->s=s;
- }
- }
- return(pv1);
- }
-
- POV_OBJ *new_obj(void) { return(obj_all[new_objz()]); }
-
- int new_objz(void)
- {
- POV_OBJ *pv;
- int k;
- static char msg[]="Creating new object";
-
- for(k=0,pv=(POV_OBJ *)NULL;pv==(POV_OBJ *)NULL;k++)
- {
- if(k>=PSIZE) t_error(msg,3);
- if(obj_all[k]==(POV_OBJ *)NULL)
- {
- if((pv=(POV_OBJ *)malloc(sizeof(POV_OBJ)))==(void *)NULL)
- t_error(msg,1);
- obj_all[k]=pv;
- }
- else
- if(obj_all[k]->cnt==0) pv=obj_all[k];
- }
-
- pv->c=(char)0;
- pv->cnt=1;
- pv->tex=(POV_OBJ *)NULL;
- pv->bound=(POV_OBJ *)NULL;
- (pv->b)[0]=0; (pv->b)[1]=0; (pv->b)[2]=0;
- (pv->u)[0]=1; (pv->u)[1]=0; (pv->u)[2]=0;
- (pv->v)[0]=0; (pv->v)[1]=1; (pv->v)[2]=0;
- (pv->w)[0]=0; (pv->w)[1]=0; (pv->w)[2]=1;
- pv->s=(char *)NULL;
- return(k-1);
- }
-
-
- char *cp_str(char *s)
- {
- static char msg[]="Copying string.";
- char *s1; int n;
-
- if(s==(char *)NULL) return(s);
- n=strlen(s);
- n=(n/SSIZE+1)*SSIZE;
- if((s1=(char *)malloc(n))==(char *)NULL) t_error(msg,1);
- strcpy(s1,s);
- return(s1);
- }
-
- FILE *save_program( int n1, int n2, char *str )
- {
- int i;
- static FILE *savep;
-
- if((savep=fopen(str,"w"))==NULL) return(NULL);
- for(i=n1; (i<=n2) && (program[i].n>=0); i++)
- {
- fprintf(savep,"%-6d ",transl_flag!=2 ? program[i].n : 10*(i+1));
- fprintf(savep,"%s\n",retransl_line(program[i].s));
- }
- fclose(savep);
- return(savep);
- }
-
- int get4hex(char *s)
- {
- int i,n;
- char c;
- static char msg[]="Decoding hex number.";
-
- for(i=0,n=0;i<4;i++)
- {
- c=*(s+i);
- c=(c>='A') ? (c-'A'+10) : (c-'0');
- if(c&~0XF) t_error(msg,3);
- n=(n<<4)+c;
- }
- return(n);
- }
-
-
- void free_obj(POV_OBJ *pv)
- {
- if(pv->cnt!=1) t_error("Object cannot be deleted. It is used.",3);
- del_obj(pv); pv->cnt=1;
- return;
- }
-
- void del_obj(POV_OBJ *pv)
- {
- char *s; int n;
- char msg[]="Deleting object.";
-
- if(pv==(POV_OBJ *)NULL) t_error(msg,3);
- if(pv->cnt<1) t_error(msg,3);
- if(pv->c>0)
- {
- if(pv->s==(char *)NULL) t_error(msg,4);
- for(s=pv->s;*s;s+=5)
- {
- n=GET4HEX(s+1);
- del_obj(obj_all[n]);
- }
- }
-
- if(pv->tex!=(POV_OBJ *)NULL) del_obj(pv->tex);
- if(pv->bound!=(POV_OBJ *)NULL) del_obj(pv->bound);
- if(pv->cnt==1)
- {
- if(pv->s!=(char *)NULL) free(pv->s); pv->s=(char *)NULL;
- pv->c=0;
- (pv->b)[0]=0; (pv->b)[1]=0; (pv->b)[2]=0;
- (pv->u)[0]=1; (pv->u)[1]=0; (pv->u)[2]=0;
- (pv->v)[0]=0; (pv->v)[1]=1; (pv->v)[2]=0;
- (pv->w)[0]=0; (pv->w)[1]=0; (pv->w)[2]=1;
- pv->tex=(POV_OBJ *)NULL;
- pv->bound=(POV_OBJ *)NULL;
- }
- pv->cnt-=1;
- return;
- }
-
- /* Makes a copy of texture and bound, if more than 1 parent */
- POV_OBJ *cp_tbx(POV_OBJ *p)
- {
- POV_OBJ *pv;
-
- pv=p->tex;
- if(pv!=(POV_OBJ *)NULL)
- if(pv->cnt>1)
- { p->tex=obj_asn((POV_OBJ *)NULL,pv);
- del_obj(pv); }
- pv=p->bound;
- if(pv!=(POV_OBJ *)NULL)
- if(pv->cnt>1)
- { p->bound=obj_asn((POV_OBJ *)NULL,pv);
- del_obj(pv); }
- return(p);
- }
-
- POV_OBJ *yscale1(POV_OBJ *p,VECTOR v)
- { if(p==(POV_OBJ *)NULL) return(p);
- scale(p->b,v,p->b); scale(p->u,v,p->u);
- scale(p->v,v,p->v); scale(p->w,v,p->w);
- return(p); }
-
- POV_OBJ *yscale2(POV_OBJ *p,VECTOR v)
- { if(p==(POV_OBJ *)NULL) return(p);
- vecscale(p->u,v[0],p->u); vecscale(p->v,v[1],p->v);
- vecscale(p->w,v[2],p->w);
- return(p); }
-
- POV_OBJ *yrot1(POV_OBJ *p,VECTOR v)
- { if(p==(POV_OBJ *)NULL) return(p);
- rotxyz(p->b,v,p->b); rotxyz(p->u,v,p->u);
- rotxyz(p->v,v,p->v); rotxyz(p->w,v,p->w);
- return(p); }
-
- POV_OBJ *yrot2(POV_OBJ *p,VECTOR v)
- { VECTOR vu,vv,vw,vt;
- if(p==(POV_OBJ *)NULL) return(p);
- vecx(vu); vecy(vv); vecz(vw);
- rotxyz(vu,v,vu); rotxyz(vv,v,vv); rotxyz(vw,v,vw);
- vt[0]=vecabs(p->u); vt[1]=vecabs(p->v); vt[2]=vecabs(p->w);
- vecscale(p->u,1/vt[0],p->u);
- vecscale(p->v,1/vt[1],p->v);
- vecscale(p->w,1/vt[2],p->w);
- transformc(vu,vu,p->u,p->v,p->w);
- transformc(vv,vv,p->u,p->v,p->w);
- transformc(vw,vw,p->u,p->v,p->w);
- vecscale(p->u,vt[0],vu);
- vecscale(p->v,vt[1],vv);
- vecscale(p->w,vt[2],vw);
- return(p); }
-
- POV_OBJ *ytransl1(POV_OBJ *p,VECTOR v)
- { if(p==(POV_OBJ *)NULL) return(p);
- vecadd(p->b,v,p->b);
- return(p); }
-
- POV_OBJ *ytransl2(POV_OBJ *p,VECTOR v)
- { VECTOR vt;
- if(p==(POV_OBJ *)NULL) return(p);
- transformc(vt,v,p->u,p->v,p->w);
- vecadd(p->b,vt,p->b);
- return(p); }
-
-
-
- /* makes an object fitting into it's bounds */
- POV_OBJ *fit_obj(POV_OBJ *pv)
- {
- char *s; int n;
- VECTOR p0,px,py,pz;
- POV_OBJ *p,*q;
- double d,db,dx0,dx1,dy0,dy1,dz0,dz1;
-
- if(pv->bound==(POV_OBJ *)NULL) pv->bound=new_obj();
- if(pv->c==0) return(pv);
- dx0=dx1=dy0=dy1=dz0=dz1=0; /* stop warning */
-
- for(s=pv->s,n=0;*s;s+=5,n++)
- {
- p=obj_all[get4hex(s+1)];
- q=p->bound;
- if(q==(POV_OBJ *)NULL)
- {
- vecasn(p0,p->b); vecasn(px,p->u); vecasn(py,p->v); vecasn(pz,p->w);
- }
- else
- {
- transformc(p0,q->b,p->u,p->v,p->w);
- vecadd(p0,p->b,p0);
- transformc(px,q->u,p->u,p->v,p->w);
- transformc(py,q->v,p->u,p->v,p->w);
- transformc(pz,q->w,p->u,p->v,p->w);
- }
-
- q=pv->bound;
- /* d is maximal distance from p->u */
- db=dist2(q->u,p0);
- d=fabs(dist2(q->u,px))+fabs(dist2(q->u,py))+fabs(dist2(q->u,pz));
- if(dx0>db-d || !n) dx0=db-d; if(dx1<db+d || !n) dx1=db+d;
-
- db=dist2(q->v,p0);
- d=fabs(dist2(q->v,px))+fabs(dist2(q->v,py))+fabs(dist2(q->v,pz));
- if(dy0>db-d || !n) dy0=db-d; if(dy1<db+d || !n) dy1=db+d;
-
- db=dist2(q->w,p0);
- d=fabs(dist2(q->w,px))+fabs(dist2(q->w,py))+fabs(dist2(q->w,pz));
- if(dz0>db-d || !n) dz0=db-d; if(dz1<db+d || !n) dz1=db+d;
- }
-
- q=pv->bound;
- db=(dx0+dx1)/2; d=(dx1-dx0)/2;
- vecscale(q->b,db,q->u); vecscale(q->u,d,q->u);
- db=(dy0+dy1)/2; d=(dy1-dy0)/2;
- vecscale(p0,db,q->v); vecadd(q->b,p0,q->b); vecscale(q->v,d,q->v);
- db=(dz0+dz1)/2; d=(dz1-dz0)/2;
- vecscale(p0,db,q->w); vecadd(q->b,p0,q->b); vecscale(q->w,d,q->w);
- return(q);
- }
-
-
- /* automatic bound */
- POV_OBJ *bound_obj(POV_OBJ *pv)
- {
- char *s; int n;
- POV_OBJ *q,*pp;
- double d,vol,a,b,c;
- VECTOR v,vb,vx,vy,vz;
-
- q=pv->bound;
- if(q!=(POV_OBJ *)NULL) return(q);
- pv->bound=new_obj();
- pp=pv->bound;
-
- switch(pv->c)
- {
- case 0: /* primitive */
- break;
-
- default:
- case 1: /* union */
- for(s=pv->s;*s;s+=5)
- { n=get4hex(s+1);
- q=obj_all[n];
- if((q->c!=0) && (q->bound==(POV_OBJ *)NULL)) bound_obj(q);
- }
-
- vol=-1;
- for(v[0]=0; v[0]<M_PI*5/12; v[0]+=M_PI/6)
- for(v[1]=0; v[1]<M_PI*5/12; v[1]+=M_PI/6)
- for(v[2]=0; v[2]<M_PI*5/12; v[2]+=M_PI/6)
- {
- q=cp_tmp(pp);
- rotxyz(q->u,v,q->u);
- rotxyz(q->v,v,q->v);
- rotxyz(q->w,v,q->w);
- pv->bound=q;
- q=fit_obj(pv);
- a=vecabs(q->u); b=vecabs(q->v); c=vecabs(q->w);
- d=a*b+a*c+b*c; /* area */
- if(d<vol || vol<0)
- { vol=d;
- vecasn(vb,q->b); vecasn(vx,q->u);
- vecasn(vy,q->v); vecasn(vz,q->w);
- }
- }
- pv->bound=pp;
- vecasn(pp->b,vb); vecscale(pp->u,1.01,vx);
- vecscale(pp->v,1.01,vy); vecscale(pp->w,1.01,vz);
- break;
-
- case 2: /* intersection, looking for the smallest bound */
- for(s=pv->s,vol=-1;*s;s+=5)
- { n=get4hex(s+1);
- q=obj_all[n];
- if((q->c!=0) && (q->bound==(POV_OBJ *)NULL)) bound_obj(q);
- if(q->bound!=(POV_OBJ *)NULL) q=q->bound;
- a=vecabs(q->u); b=vecabs(q->v); c=vecabs(q->w);
- d=a*b+a*c+b*c; /* area */
- if(d<vol || vol<0)
- { vol=d;
- vecasn(vb,q->b); vecasn(vx,q->u);
- vecasn(vy,q->v); vecasn(vz,q->w);
- }
- }
- vecasn(pp->b,vb); vecscale(pp->u,1.01,vx);
- vecscale(pp->v,1.01,vy); vecscale(pp->w,1.01,vz);
- break;
-
- case 3: /* difference */
- for(s=pv->s;*s;s+=5)
- { n=get4hex(s+1);
- q=obj_all[n];
- if((q->c!=0) && (q->bound==(POV_OBJ *)NULL)) bound_obj(q);
- }
-
- n=get4hex((pv->s)+1);
- q=obj_all[n];
- if(q->bound!=(POV_OBJ *)NULL) q=q->bound;
- vecasn(pp->b,q->b);
- vecasn(pp->u,q->u);
- vecasn(pp->v,q->v);
- vecasn(pp->w,q->w);
- break;
-
- }
- pp->s=cp_str("box {<-1,-1,-1>< 1, 1, 1>}");
- return(pp);
- }
-
-
-
- /* Print Object */
- static int pr_level=0;
- #define PPR for(i=0;i<15 && i<pr_level;i++) putc(' ',fep),putc(' ',fep);
- void print_obj( FILE *fep, POV_OBJ *pv )
- {
- VECTOR v;
- int n,i;
- char *s;
- static char msg[]="Printing object or CSG object";
-
-
- switch(pv->c)
- {
- case 1: PPR; fprintf(fep,"union"); goto la_po1;
- case 2: PPR; fprintf(fep,"intersection"); goto la_po1;
- case 3: PPR; fprintf(fep,"difference"); goto la_po1;
-
- la_po1: fprintf(fep," {\n");
- if(pv->s!=(char *)NULL)
- for(s=pv->s;*s;s+=5)
- {
- n=GET4HEX(s+1);
- if((n<0) || (n>=PSIZE) || (obj_all[n]==(POV_OBJ *)NULL))
- t_error(msg,3);
- pr_level++;
- print_obj(fep,obj_all[n]);
- pr_level--;
- }
- goto la_po2;
- default:
- case 0: PPR; fprintf(fep,"object { ");
- if(pv->s!=(char *)NULL) fprintf(fep,"%s\n",pv->s);
- else fprintf(fep,"sphere { <0,0,0>,1 }\n");
- goto la_po2;
- case -1: PPR; fprintf(fep,"texture { ");
- if(pv->s!=(char *)NULL) fprintf(fep,"%s\n",pv->s);
- else fprintf(fep,"MyTexture\n");
- goto la_po3;
- la_po2:
- if(pv->bound!=(POV_OBJ *)NULL)
- {
- pr_level++;
- PPR; fprintf(fep,"bounded_by {\n");
- pr_level++; print_obj(fep,pv->bound); pr_level--;
- PPR; fprintf(fep,"}\n");
- PPR; fprintf(fep,"clipped_by { bounded_by }\n");
- pr_level--;
- }
- if(pv->tex!=(POV_OBJ *)NULL)
- {
- n=(pv->tex)->c; (pv->tex)->c=-1;
- pr_level++; print_obj(fep,pv->tex); pr_level--;
- (pv->tex)->c=n;
- }
-
- la_po3: v[0]=vecabs(pv->u); v[1]=vecabs(pv->v); v[2]=vecabs(pv->w);
- if((v[0]!=1) || (v[1]!=1) || (v[2]!=1))
- { PPR; fprintf(fep," scale <%G,%G,%G>\n",v[0],v[1],v[2]); }
- if(vecabs(pv->u)<=0) t_error(msg,3);
- if(vecabs(pv->v)<=0) t_error(msg,3);
- if(vecabs(pv->w)<=0) t_error(msg,3);
- getrotxyz(v,pv->u,pv->v,pv->w);
- if((v[0]!=0) || (v[1]!=0) || (v[2]!=0))
- {
- PPR; fprintf(fep," rotate <%G,%G,%G>\n",
- v[0]*180/M_PI,v[1]*180/M_PI,v[2]*180/M_PI);
- }
- vecasn(v,pv->b);
- if((v[0]!=0) || (v[1]!=0) || (v[2]!=0))
- { PPR;
- fprintf(fep," translate <%G,%G,%G> \n", v[0],v[1],v[2]); }
- PPR; fprintf(fep,"}\n");
- break;
- }
- return;
- }
-
-